﻿using System;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
using log4net;

namespace ArrowWebParts
{
    class DashboardWidgetEditorPart : EditorPart
    {
        #region fields

        //private TextBox rptDefUrlTextBox;
        //private RequiredFieldValidator rptDefUrlTextBoxRequiredFieldValidator;
        private TextBox refreshTimeTextBox;
        private RequiredFieldValidator refreshTimeTextBoxReqValidator;
        private RegularExpressionValidator refreshTimeTextBoxRegExValidator;
        private TextBox frameHeightTextBox;
        private RequiredFieldValidator frameHeightTextBoxReqValidator;
        private RegularExpressionValidator frameHeightTextBoxRegExValidator;
        private CheckBox scrollbarDisplayCheckBox;
        private TextBox defaultVariableValueTextBox;
        //private RequiredFieldValidator defaultVariableValueTextBoxRequiredFieldValidator;

        private DropDownList sitesDropDownList;
        private DropDownList documentLibrariesDropDownList;
        private DropDownList filesDropDownList;

        private static ILog log = LogManager.GetLogger(typeof(DashboardWidgetEditorPart));

        #endregion

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            if (log.IsDebugEnabled)
                log.Debug("Creating child controls.");

            try
            {
                Title = "Arrow Dashboard Widget Properties";

                ToolPane pane = Zone as ToolPane;
                if (pane != null)
                    pane.Cancel.CausesValidation = false;

                generateAndAddEditorPartTextBox("Refresh Time (seconds)", "Input the amount of time between refreshes.  Input 0 to have it not refresh automatically.", out refreshTimeTextBox);
                refreshTimeTextBox.ID = "refreshTimeTextBox";
                refreshTimeTextBoxReqValidator = new RequiredFieldValidator();
                refreshTimeTextBoxReqValidator.ControlToValidate = "refreshTimeTextBox";
                refreshTimeTextBoxReqValidator.Display = ValidatorDisplay.Dynamic;
                refreshTimeTextBoxReqValidator.Text = "* Enter an positive integer (0, 1, 2, 3...)";
                Controls.Add(refreshTimeTextBoxReqValidator);
                refreshTimeTextBoxRegExValidator = new RegularExpressionValidator();
                refreshTimeTextBoxRegExValidator.ControlToValidate = "refreshTimeTextBox";
                refreshTimeTextBoxRegExValidator.Display = ValidatorDisplay.Dynamic;
                refreshTimeTextBoxRegExValidator.ValidationExpression = @"\d+";
                refreshTimeTextBoxRegExValidator.Text = "* Enter an positive integer (0, 1, 2, 3...)";
                Controls.Add(refreshTimeTextBoxRegExValidator);

                Controls.Add(new LiteralControl("<br/><DIV class=\"UserDottedLine\" width=\"100%\"></DIV>"));
                generateAndAddEditorPartTextBox("Dashboard Widget Height (pixels)", "Input the desired height of the widget.  Input 0 to have it attempt to automatically size the widget.", out frameHeightTextBox);
                frameHeightTextBox.ID = "frameHeightTextBox";
                frameHeightTextBoxReqValidator = new RequiredFieldValidator();
                frameHeightTextBoxReqValidator.ControlToValidate = "frameHeightTextBox";
                frameHeightTextBoxReqValidator.Display = ValidatorDisplay.Dynamic;
                frameHeightTextBoxReqValidator.Text = "* Enter an positive integer (0, 1, 2, 3...)";
                Controls.Add(frameHeightTextBoxReqValidator);
                frameHeightTextBoxRegExValidator = new RegularExpressionValidator();
                frameHeightTextBoxRegExValidator.ControlToValidate = "frameHeightTextBox";
                frameHeightTextBoxRegExValidator.Display = ValidatorDisplay.Dynamic;
                frameHeightTextBoxRegExValidator.ValidationExpression = @"\d+";
                frameHeightTextBoxRegExValidator.Text = "* Enter an positive integer (0, 1, 2, 3...)";
                Controls.Add(frameHeightTextBoxRegExValidator);

                Controls.Add(new LiteralControl("<br/><DIV class=\"UserDottedLine\" width=\"100%\"></DIV>"));
                // function to create and add the checkbox
                generateAndAddEditorPartCheckBox("Display scrollbars?", "Check to enable scroll bars.  Uncheck to disable scrollbars.", out scrollbarDisplayCheckBox);

                Controls.Add(new LiteralControl("<br/><DIV class=\"UserDottedLine\" width=\"100%\"></DIV>"));
                generateAndAddEditorPartTextBox("Default value for variables", "Default value for variables that are not set by the dashboard controller.", out defaultVariableValueTextBox);
                defaultVariableValueTextBox.ID = "defaultVariableValueTextBox";
                /*defaultVariableValueTextBoxRequiredFieldValidator = new RequiredFieldValidator();
                defaultVariableValueTextBoxRequiredFieldValidator.Display = ValidatorDisplay.Dynamic;
                defaultVariableValueTextBoxRequiredFieldValidator.ErrorMessage = "* Enter a default value";
                defaultVariableValueTextBoxRequiredFieldValidator.Text = "* Enter a default value";
                defaultVariableValueTextBoxRequiredFieldValidator.ControlToValidate = "defaultVariableValueTextBox";
                Controls.Add(defaultVariableValueTextBoxRequiredFieldValidator);*/

                /*Controls.Add(new LiteralControl("<br/><DIV class=\"UserDottedLine\" width=\"100%\"></DIV>"));
                TextBox rptDefUrlTextBox;
                generateAndAddEditorPartTextBox("Report Definition URL", "Report Definition URL to be used.", out rptDefUrlTextBox);
                rptDefUrlTextBox.ID = "rptDefUrlTextBox";
                rptDefUrlTextBoxRequiredFieldValidator = new RequiredFieldValidator();
                rptDefUrlTextBoxRequiredFieldValidator.Display = ValidatorDisplay.Dynamic;
                rptDefUrlTextBoxRequiredFieldValidator.ErrorMessage = "* Enter a URL";
                rptDefUrlTextBoxRequiredFieldValidator.Text = "* Enter a URL";
                rptDefUrlTextBoxRequiredFieldValidator.ControlToValidate = "rptDefUrlTextBox";
                Controls.Add(rptDefUrlTextBoxRequiredFieldValidator);*/

                Controls.Add(new LiteralControl("<br/><DIV class=\"UserDottedLine\" width=\"100%\"></DIV>"));
                Controls.Add(new LiteralControl("<DIV class=\"UserSectionHead\">"));
                Controls.Add(new Label { Text = "Select Report Definition/Template", ToolTip = "This tools helps you select a report definition/template and set variable values." });
                Controls.Add(new LiteralControl("<br/><br/>"));
                Controls.Add(new LiteralControl("</DIV>"));

                Controls.Add(new LiteralControl("<u>1. Locate the report definition/template file</u><br/>"));

                Controls.Add(new LiteralControl("Site<br/>"));
                sitesDropDownList = new DropDownList();
                sitesDropDownList.SelectedIndexChanged += new EventHandler(sitesDropDownList_SelectedIndexChanged);
                sitesDropDownList.AutoPostBack = true;
                SPSite oSiteCollection = SPContext.Current.Site;

                SPWebCollection collWebsite = ArrowUtils.GetSPWebCollectionFromCurrentSite();
                foreach (SPWeb oWebsite in collWebsite)
                {
                    sitesDropDownList.Items.Add(new ListItem(oWebsite.Title, oWebsite.ID.ToString()));
                    oWebsite.Dispose();
                }

                sitesDropDownList.SelectedIndex = sitesDropDownList.Items.IndexOf(sitesDropDownList.Items.FindByValue(SPContext.Current.Web.ID.ToString()));
                Controls.Add(sitesDropDownList);

                Controls.Add(new LiteralControl("<br/>Document Library<br/>"));
                documentLibrariesDropDownList = new DropDownList();
                documentLibrariesDropDownList.SelectedIndexChanged += new EventHandler(documentLibrariesDropDownList_SelectedIndexChanged);
                documentLibrariesDropDownList.AutoPostBack = true;
                Controls.Add(documentLibrariesDropDownList);

                Controls.Add(new LiteralControl("<br/>File<br/>"));
                filesDropDownList = new DropDownList();
                Controls.Add(filesDropDownList);

                sitesDropDownList_SelectedIndexChanged(null, null);
            }
            catch (Exception ex)
            {
                ArrowUtils.LogFatalException(log, ex);
                Controls.Clear();
                Controls.Add(new LiteralControl(string.Format("There was an error creating the dashboard widget editor part: {0}", ex.Message)));
                return;
            }

            if (log.IsDebugEnabled)
                log.Debug("Finished creating child controls.");
        }

        public override void SyncChanges()
        {
            if (log.IsDebugEnabled)
                log.Debug("Syncing changes.");

            try
            {
                EnsureChildControls();
                DashboardWidgetWebPart sourcePart = (DashboardWidgetWebPart)this.WebPartToEdit;
                //rptDefUrlTextBox.Text = sourcePart.ReportDefinitionUrl;
                refreshTimeTextBox.Text = sourcePart.RefreshTime.ToString();
                frameHeightTextBox.Text = sourcePart.FrameHeight.ToString();
                scrollbarDisplayCheckBox.Checked = sourcePart.ScrollbarDisplay;
                defaultVariableValueTextBox.Text = sourcePart.DefaultVariableValue;

                if (sourcePart.SiteGuid != Guid.Empty)
                {
                    if (sitesDropDownList.Items.FindByValue(sourcePart.SiteGuid.ToString()) != null)
                    {
                        sitesDropDownList.SelectedIndex = sitesDropDownList.Items.IndexOf(sitesDropDownList.Items.FindByValue(sourcePart.SiteGuid.ToString()));
                        sitesDropDownList_SelectedIndexChanged(null, null);

                        if (documentLibrariesDropDownList.Items.FindByValue(sourcePart.DocLibGuid.ToString()) != null)
                        {
                            documentLibrariesDropDownList.SelectedIndex = documentLibrariesDropDownList.Items.IndexOf(documentLibrariesDropDownList.Items.FindByValue(sourcePart.DocLibGuid.ToString()));
                            documentLibrariesDropDownList_SelectedIndexChanged(null, null);

                            if (filesDropDownList.Items.FindByValue(sourcePart.FileGuid.ToString()) != null)
                            {
                                filesDropDownList.SelectedIndex = filesDropDownList.Items.IndexOf(filesDropDownList.Items.FindByValue(sourcePart.FileGuid.ToString()));
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ArrowUtils.LogFatalException(log, ex);
                Controls.Clear();
                Controls.Add(new LiteralControl(string.Format("There was an error syncing changes: {0}", ex.Message)));
                return;
            }

            if (log.IsDebugEnabled)
                log.Debug("Finished syncing changes.");
        }

        public override bool ApplyChanges()
        {
            if (log.IsDebugEnabled)
                log.Debug("Applying changes.");

            try
            {
                EnsureChildControls();
                DashboardWidgetWebPart targetPart = (DashboardWidgetWebPart)this.WebPartToEdit;
                if (targetPart != null)
                {
                    //targetPart.ReportDefinitionUrl = rptDefUrlTextBox.Text.Trim();
                    targetPart.RefreshTime = Convert.ToInt32(refreshTimeTextBox.Text.Trim());
                    targetPart.FrameHeight = Convert.ToInt32(frameHeightTextBox.Text.Trim());
                    targetPart.ScrollbarDisplay = scrollbarDisplayCheckBox.Checked;
                    targetPart.DefaultVariableValue = defaultVariableValueTextBox.Text.Trim();

                    if (sitesDropDownList.SelectedValue != "")
                    {
                        targetPart.SiteGuid = new Guid(sitesDropDownList.SelectedValue);
                        if (documentLibrariesDropDownList.SelectedValue != "")
                        {
                            targetPart.DocLibGuid = new Guid(documentLibrariesDropDownList.SelectedValue);
                            if (filesDropDownList.SelectedValue != "")
                            {
                                targetPart.FileGuid = new Guid(filesDropDownList.SelectedValue);
                                targetPart.ReportDefinitionUrl = generateRptDefPath();
                            }
                        }
                    }
                }
                else
                {
                    if (log.IsDebugEnabled)
                        log.Debug("Finished applying changes.");
                    return false;
                }

                if (log.IsDebugEnabled)
                    log.Debug("Finished applying changes.");

                return true;
            }
            catch (Exception ex)
            {
                ArrowUtils.LogFatalException(log, ex);
                Controls.Clear();
                Controls.Add(new LiteralControl(string.Format("There was an error applying changes: {0}", ex.Message)));
                return false;
            }
        }

        private string generateRptDefPath()
        {
            SPSite oSiteCollection = SPContext.Current.Site;

            SPWebCollection collWebsite = ArrowUtils.GetSPWebCollectionFromCurrentSite();
            Guid siteGuid = new Guid(sitesDropDownList.SelectedValue);
            SPWeb site = collWebsite[siteGuid];

            Guid libraryID = new Guid(documentLibrariesDropDownList.SelectedValue);
            SPDocumentLibrary library = (SPDocumentLibrary)site.Lists[libraryID];

            Guid fileID = new Guid(filesDropDownList.SelectedValue);
            SPFile file = library.Items[fileID].File;

            string relativePath = file.ServerRelativeUrl;
            string absolutePath = SPContext.Current.Site.MakeFullUrl(relativePath);

            return absolutePath;

        }

        private void generateAndAddEditorPartTextBox(string propertyName, string toolTip, out TextBox tex)
        {
            Controls.Add(new LiteralControl("<DIV class=\"UserSectionHead\">"));
            Controls.Add(new Label { Text = propertyName, ToolTip = toolTip });
            Controls.Add(new LiteralControl("</DIV>"));
            Controls.Add(new LiteralControl("<DIV class=\"UserSectionBody\">"));
            Controls.Add(new LiteralControl("<DIV class=\"UserControlGroup\">"));
            Controls.Add(new LiteralControl("<NOBR>"));
            tex = new TextBox();
            tex.CssClass = "UserInput";
            Controls.Add(tex);
            Controls.Add(new LiteralControl("<NOBR>"));
            Controls.Add(new LiteralControl("<DIV class=\"UserSectionBody\">"));
            Controls.Add(new LiteralControl("<DIV class=\"UserControlGroup\">"));
        }

        private void generateAndAddEditorPartCheckBox(string propertyName, string toolTip, out CheckBox che)
        {
            Controls.Add(new LiteralControl("<DIV class=\"UserSectionHead\">"));
            Controls.Add(new Label { Text = propertyName, ToolTip = toolTip });
            Controls.Add(new LiteralControl("</DIV>"));
            Controls.Add(new LiteralControl("<DIV class=\"UserSectionBody\">"));
            Controls.Add(new LiteralControl("<DIV class=\"UserControlGroup\">"));
            Controls.Add(new LiteralControl("<NOBR>"));
            che = new CheckBox();
            che.CssClass = "UserInput";
            Controls.Add(che);
            Controls.Add(new LiteralControl("<NOBR>"));
            Controls.Add(new LiteralControl("<DIV class=\"UserSectionBody\">"));
            Controls.Add(new LiteralControl("<DIV class=\"UserControlGroup\">"));
        }

        #region delegate functions

        void sitesDropDownList_SelectedIndexChanged(object sender, EventArgs e)
        {
            documentLibrariesDropDownList.Items.Clear();
            if (sitesDropDownList.Items.Count != 0)
            {
                SPWebCollection collWebsite = ArrowUtils.GetSPWebCollectionFromCurrentSite();
                Guid siteGuid = new Guid(sitesDropDownList.SelectedValue);
                SPWeb site = collWebsite[siteGuid];
                foreach (SPList list in site.Lists)
                {
                    if (list is SPDocumentLibrary && !list.Hidden)
                    {
                        documentLibrariesDropDownList.Items.Add(new ListItem(list.Title, list.ID.ToString()));
                    }
                }

            }
            documentLibrariesDropDownList_SelectedIndexChanged(null, null);
        }

        void documentLibrariesDropDownList_SelectedIndexChanged(object sender, EventArgs e)
        {
            filesDropDownList.Items.Clear();
            if (documentLibrariesDropDownList.Items.Count != 0)
            {
                SPWebCollection collWebsite = ArrowUtils.GetSPWebCollectionFromCurrentSite();
                Guid siteGuid = new Guid(sitesDropDownList.SelectedValue);
                SPWeb site = collWebsite[siteGuid];

                Guid libraryID = new Guid(documentLibrariesDropDownList.SelectedValue);
                SPDocumentLibrary library = (SPDocumentLibrary)site.Lists[libraryID];

                foreach (SPListItem item in library.Items)
                {
                    SPFile file = item.File;
                    if (file.Name.EndsWith(".reportdef") || file.Name.EndsWith(".wrf") || file.Name.EndsWith(".docx") || file.Name.EndsWith(".xlsx") || file.Name.EndsWith(".pptx"))
                        filesDropDownList.Items.Add(new ListItem(file.Name, item.UniqueId.ToString()));
                }
            }

            if (documentLibrariesDropDownList.Items.Count == 0)
            {
                documentLibrariesDropDownList.Items.Add(new ListItem("<None>", ""));
                filesDropDownList.Items.Add(new ListItem("<None>", ""));
            }
            else if (filesDropDownList.Items.Count == 0)
            {
                filesDropDownList.Items.Add(new ListItem("<None>", ""));
            }

            if (sitesDropDownList.Items.Count == 0)
            {
                // Not sure how this would be possible, but just in case.
                sitesDropDownList.Items.Add(new ListItem("<None>", ""));
            }
        }

        #endregion
    }
}
